package com.ai.xmlutils;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.experimental.UtilityClass;
import lombok.val;

@UtilityClass
public class XmlMinifier {
    public String minify(String xml) {
        val sb = new StringBuilder();

        int startPos = 0;
        while (true) {
            val openTag = findOpenTag(xml, startPos);
            if (openTag == Tag.NONE) return xml;

            val closeTag = findCloseTag(xml, openTag);
            startPos = closeTag.getEndPos() + 1;

            val value = retrieveValue(xml, openTag, closeTag);
            val subMinified = openTag.getName() + ":" + minify(value) + "$";
            sb.append(subMinified);

            if (closeTag.getEndPos() == xml.length() - 1) break;
        }

        return sb.toString();
    }

    private Tag findOpenTag(String xml, int startIndex) {
        int startPos = xml.indexOf('<', startIndex);
        if (startPos < 0) return Tag.NONE;

        int endPos = xml.indexOf('>', startPos + 1);
        String name = xml.substring(startPos + 1, endPos);

        return new Tag(startPos, endPos, name);
    }

    private Tag findCloseTag(String xml, Tag openTag) {
        String closeTag = "</" + openTag.getName() + ">";
        int startPos = xml.indexOf(closeTag);
        int endPos = startPos + closeTag.length() - 1;
        return new Tag(startPos, endPos, openTag.getName());
    }

    private String retrieveValue(String xml, Tag openTag, Tag closeTag) {
        String sub = xml.substring(openTag.getEndPos() + 1, closeTag.getStartPos());
        return sub.trim();
    }

    @Data @AllArgsConstructor
    private static class Tag {
        public static final Tag NONE = new Tag(-1, -1, "");

        int startPos;
        int endPos;
        String name;
    }

}
